# -*- coding:utf-8 -*-
import shutil
import subprocess
from time import strftime, localtime, time
import json
import pickle
import random
import string
import os

import requests
import yaml

from Lib import cryptoObj
from Util import config
from Util.exception import ZTCCLOUDError


# 生成随机字符串
def gen_random_str(dataType: str = "all", length: int = 16, isUnique: bool = False) -> str:
    """
    生成随机字符串
    :param dataType: 字符类型  {"all": "大小写字母+数字","str": "大小写字母", "lower": "小写字母", "upper": "大写字母", "num": "数字"}
    :param length: 长度
    :param isUnique: 是否唯一
    :return:
    """
    if dataType == "all":
        allString = string.ascii_letters + string.digits
    elif dataType == "str":
        allString = string.ascii_letters
    elif dataType == "lower":
        allString = string.ascii_lowercase
    elif dataType == "upper":
        allString = string.ascii_uppercase
    elif dataType == "num":
        allString = string.digits
    else:
        raise ZTCCLOUDError(f"不支持 {dataType} 类型，请与管理员联系")
    if isUnique:
        strLength = len(allString)
        if length > strLength:
            raise ZTCCLOUDError(f"无法从 {strLength} 位中取出 {length} 个唯一的值")
        random_str = "".join(random.sample(allString, length))
    else:
        random_str = "".join(random.choices(allString, k=length))
    return random_str


class Cookie(object):
    # 保存cookie
    @staticmethod
    def save_cookie(driver, path) -> None:
        with open(path, 'wb') as fileHandler:
            cookies = driver.get_cookies()
            print(cookies)
            pickle.dump(cookies, fileHandler)

    # 加载cookie
    @staticmethod
    def load_cookie(driver, path) -> None:
        with open(path, 'rb') as cookiesFile:
            cookies = pickle.load(cookiesFile)
            for cookie in cookies:
                driver.add_cookie(cookie)


# 获取图片路径
def getPicturePath(state, imgName) -> str:
    if state == 'success':
        code = 'success_picture'
    else:
        code = 'wrong_picture'
    picture_path = f"{os.path.join(config.imagePath, code, imgName)}.png"
    return picture_path


# 获取当前时间
def getNowTime():
    timeNow = strftime("%Y-%m-%d %H:%M:%S", localtime(time()))
    return timeNow


# 单例模式
class Singleton(object):
    """
        单例模式（装饰类的类装饰器）
    """

    instances = {}

    def __init__(self, cls: type):
        self.cls = cls
        self.cls_name = cls.__name__

    def __call__(self, *args, **kwargs):
        if self.cls_name not in __class__.instances:
            __class__.instances[self.cls_name] = self.cls(*args, **kwargs)
        return __class__.instances[self.cls_name]


# 写入记录文件
def writeBoeNum(path, boeNum):
    with open(path, "r", encoding="UTF-8") as f:
        Rdata = json.load(f)
    Rdata["data"].update({'boeNum': boeNum})
    data = Rdata
    with open(path, "w", encoding="UTF-8") as f:
        json.dump(data, f)


def writeInvoiceNum(path, invoiceNum):
    with open(path, "r", encoding="UTF-8") as f:
        Rdata = json.load(f)
    Rdata["data"].update({'invoiceNum': invoiceNum})
    data = Rdata
    with open(path, "w", encoding="UTF-8") as f:
        json.dump(data, f)


# 读取记录文件
def readBoeNum(path):
    with open(path, "r", encoding="UTF-8") as f:
        Rdata = json.load(f)
    return Rdata['data']['boeNum']


def readInvoiceNum(path):
    with open(path, "r", encoding="UTF-8") as f:
        Rdata = json.load(f)
    return Rdata['data']['invoiceNum']


# 获取业务报账区域菜单分类关系
def getBasMenuCategoryRelation():
    cookie = None
    baseUrl = config.urlDict.url.basHost.rsplit("/", 1)[0]
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cookie': cookie
    }

    def getCookie():
        url = baseUrl + '/sys/auth/login'
        user = config.urlDict.userInfo.user
        data = {
            'loginKey': user.account,
            'password': cryptoObj.encrypt(user.password)
        }
        response = requests.post(url, headers=headers, data=data)
        nonlocal cookie
        cookie = ';'.join(f'{i[0]}={i[1]}' for i in response.cookies.items())
        return getMenuCodeAndName()

    def getMenuCodeAndName():
        url = baseUrl + '/sys/common/menu/nav'
        headers['Cookie'] = cookie
        params = {
            'modules': 'bas',
            '_t': int(time())
        }
        response = requests.get(url, headers=headers, params=params)
        result = response.json()['data'][0]['children']
        dataDict = {i['boeClassify']: i['name'] for i in result}
        return getBoeCodeAndName(dataDict)

    def getBoeCodeAndName(menuDict):
        url = baseUrl + '/sys/boe/initBoe/findBoeTypeByBoeClassify'
        headers['Cookie'] = cookie
        data = {
            'boeClassifyList': ','.join(menuDict.keys())
        }
        response = requests.post(url, headers=headers, data=data)
        result = response.json()['list']
        waitWriteData = {i['name']: {
            'boeClassify': menuDict[i['boeClassify']],
            'boeTypeIds': i['id'],
            'boeWaitClassify': i['boeClassify']
        }
            for i in result}
        return writeDataToYamlConf(waitWriteData)

    def writeDataToYamlConf(data):
        with open(config.basMenuConfPath, 'w', encoding='utf-8') as f:
            yaml.dump(data, f, allow_unicode=True)
        return True

    return getCookie()


# 获取业务报账区域最新的收款报账单信息，用于收款报账单流程测试场景
def getNewFundCollectionBoeInfo(boeTypeName):
    cookie = None
    baseUrl = config.urlDict.url.basHost.rsplit("/", 1)[0]
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cookie': cookie
    }

    def getCookie():
        url = baseUrl + '/sys/auth/login'
        user = config.urlDict.userInfo.user
        data = {
            'loginKey': user.account,
            'password': cryptoObj.encrypt(user.password)
        }
        response = requests.post(url, headers=headers, data=data)
        nonlocal cookie
        cookie = ';'.join(f'{i[0]}={i[1]}' for i in response.cookies.items())
        headers['Cookie'] = cookie
        return getBoeInfo()

    def getBoeInfo():
        url = baseUrl + '/sys/boe/boeList/myDocuments/page'
        boeClassify = config.basMenuConf.get(boeTypeName).boeWaitClassify
        boeTypeIds = config.basMenuConf.get(boeTypeName).boeTypeIds
        data = {
            "page": "1",
            "limit": "20",
            "orderField": "firstBoeDate",
            "order": "desc",
            "boeTypeName": boeTypeName,
            "boeTypeIds": boeTypeIds,
            "boeClassify": boeClassify,
            "boeWaitClassify": boeClassify,
            "isolationIdentification": "0"
        }
        response = requests.post(url, headers=headers, data=data)
        result = response.json()['page']['list'][0]
        boeData = {
            'boeData':{
                'boeNo': result.get('boeNo'),
                'boeType': boeTypeName
            }
        }
        with open(os.path.join(config.testDataPath, 'localMemory', 'record.json'), "w", encoding="UTF-8") as f:
            json.dump(boeData, f, ensure_ascii=False)
        from Util import logger
        logger.debug('记录文件信息, 文件信息为 -> {} : {}'.format('boeData', boeData))

    return getCookie()


# 修改报告名称
def resetReportName():
    dataPath = os.path.join(config.rootPath, 'Report', 'allure-reports', 'widgets', 'summary.json')
    with open(dataPath, "r", encoding="utf-8") as f:
        content = json.load(f)
    content['reportName'] = 'UI自动化测试报告'
    with open(dataPath, "w", encoding="utf-8") as f:
        json.dump(content, f, ensure_ascii=False)


# 存储历史数据
def saveHistoryRecordData():
    try:
        recordDataPath = os.path.join(config.rootPath, 'Report', 'allure-reports', 'widgets', 'history-trend.json')
        with open(recordDataPath, "r", encoding="utf-8") as f:
            recordData = json.load(f)
    except Exception as e:
        recordData = []
    finally:
        try:
            dataPath = os.path.join(config.rootPath, 'Report', 'recordHistory.json')
            with open(dataPath, "r", encoding="utf-8") as f:
                content = json.load(f)
        except Exception as e:
            content = []
        finally:
            content.extend(recordData)
            with open(dataPath, "w", encoding="utf-8") as f:
                json.dump(recordData, f, ensure_ascii=False)


def resetHistoryData():
    try:
        recordDataPath = os.path.join(config.rootPath, 'Report', 'recordHistory.json')
        with open(recordDataPath, "r", encoding="utf-8") as f:
            recordData = json.load(f)
    except Exception as e:
        recordData = []
    finally:
        dataPath = os.path.join(config.rootPath, 'Report', 'allure-reports', 'widgets', 'history-trend.json')
        with open(dataPath, "r", encoding="utf-8") as f:
            content = json.load(f)
        recordData.extend(content)
        with open(dataPath, "w", encoding="utf-8") as f:
            json.dump(recordData[-30:], f, ensure_ascii=False)


def deleteImages():
    """
    删除7天前的图片信息
    :return:
    """
    nowTimeStamp = time()
    waitDelDirPathList = list(os.walk(config.imagePath))[1:]
    for i in waitDelDirPathList:
        dirPath = i[0]
        for j in i[-1]:
            if j.endswith('png'):
                fileCreateTimeStamp = os.path.getctime(os.path.join(dirPath, j))
                if nowTimeStamp > fileCreateTimeStamp + 7 * 24 * 60 * 60:
                    os.remove(os.path.join(dirPath, j))


def make_archive(base_name: str, root_dir=None) -> str:
    """
    说明：
        压缩指定文件夹/目录
    :param base_name: 压缩后文件名/路径
    :param root_dir: 被压缩目录
    :return: 压缩后文件路径
    """
    return shutil.make_archive(
        base_name=base_name,
        format="zip",
        root_dir=root_dir
    )


def killChromeProcess():
    """强制关闭chrome浏览器进程"""
    # os.system('taskkill /F /IM chrome.exe > null')
    subprocess.Popen('taskkill /F /IM chrome.exe', stdout=None, stderr=None, encoding="utf-8")


if __name__ == '__main__':
    # 压缩包路径及名字
    zip_file = r'D:\lc\pythonProject\UIReportBackup\report_2021-12-11'
    killChromeProcess()
